import logging
import queue

import paho.mqtt.client as mqtt


class MQTTClient:
    def __init__(self, broker_address="123.57.81.127", broker_port=1884):
        self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        self.client.on_subscribe = self.on_subscribe
        self.client.on_unsubscribe = self.on_unsubscribe
        self.broker_address = broker_address
        self.broker_port = broker_port
        self.topic = [("iot/luoshi/alarm2", 1), ("iot/luoshi/alarm1", 1)]
        self.recv_msg = queue.Queue()

    def on_connect(self, client, userdata, flags, reason_code, properties):
        if reason_code.is_failure:
            print(f"Failed to connect: {reason_code}. loop_forever() will retry connection")
        else:
            # 确保在on_connect回调中订阅，以保证重新连接后订阅仍然有效
            client.subscribe(self.topic)

    def on_message(self, client, userdata, message):
        self.recv_msg.put(message)

        # if len(userdata) >= 10:
        #     client.unsubscribe("$SYS/#")

    def on_subscribe(self, client, userdata, mid, reason_code_list, properties):
        if reason_code_list[0].is_failure:
            print(f"Broker rejected you subscription: {reason_code_list[0]}")
        else:
            print(f"Broker granted the following QoS: {reason_code_list[0].value}")

    def on_unsubscribe(self, client, userdata, mid, reason_code_list, properties):
        if len(reason_code_list) == 0 or not reason_code_list[0].is_failure:
            print("Unsubscribe succeeded (if SUBACK is received in MQTTv3 it success)")
        else:
            print(f"Broker replied with failure: {reason_code_list[0]}")
        client.disconnect()

    def send_msg(self, payload):
        topic = "iot/luoshi/speak"
        self.client.publish(topic, payload)

    def connect_and_loop(self):
        self.client.connect(self.broker_address, self.broker_port)
        self.client.loop_forever()

    def get_received_messages(self):
        try:
            return self.recv_msg.get()
        except queue.Empty:
            pass
        except Exception as e:
            print(e)


mqtt_client = MQTTClient()
